package com.blue.http.websocket;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.task.TaskExecutor;

import com.blue.core.file.ClassScanner;
import com.blue.http.annotation.WebsocketClassHandler;
import com.blue.http.annotation.WebsocketParser;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;

/**
 * Websocket初始化器
 * 
 * @author zhengj
 * @since 1.0 2016年12月15日
 */
public class WebsocketInitializer extends ChannelInitializer<SocketChannel> implements InitializingBean, ApplicationContextAware
{
	private static Logger logger = LoggerFactory.getLogger(WebsocketInitializer.class);

	@Resource
	private WebsocketRouter websocketRouter;
	@Resource
	protected TaskExecutor taskExecutor;

	protected List<String> packageList;

	private WebsocketParser parser;
	private String root = "/ws";

	public WebsocketInitializer()
	{
	}

	@Override
	protected void initChannel(SocketChannel ch) throws Exception
	{
		ChannelPipeline cp = ch.pipeline();

		cp.addLast(new HttpServerCodec());
		cp.addLast(new HttpObjectAggregator(Short.MAX_VALUE));
		cp.addLast(new WebSocketServerCompressionHandler());
		cp.addLast(new WebSocketServerProtocolHandler(root, null, true));
		cp.addLast(new WebsocketServerHandler(taskExecutor, parser, websocketRouter));

	}

	public void setRoot(String root)
	{
		this.root = root;
	}

	@Override
	public void setApplicationContext(ApplicationContext ctx) throws BeansException
	{
		this.parser = new WebsocketParser(ctx);
	}

	@Override
	public void afterPropertiesSet() throws Exception
	{
		logger.info("扫描包：{}", packageList);
		ClassScanner scanner = new ClassScanner();
		scanner.setClassHandler(new WebsocketClassHandler(parser));
		scanner.scan(true, packageList);
	}

	public void setScanPackages(List<String> packageList)
	{
		this.packageList = packageList;
	}

}
